class displayClass
{
	private:	
		coordList *elementList;

	public:
		displayClass()
		{
			elementList = NULL;
		}
		
		~displayClass()
		{
			deleteElementInList( elementList, NULL );
		}
		
		void addElementToScreen( coordList *elementBeingAdded, coordList *&firstPrevPointer, coordList *&lastPrevPointer );
		void copyElementList( coordList *src, coordList *&target );
		void findPrevElement( coordList **, coordList *, coordList *, coordList **&, coordList *&, int flag = 1 );
		void deleteElementInList( coordList *, coordList * );
		void copyElementListAndPrevPointers( coordList *, coordList *&, coordList *&, coordList *&, coordList * = NULL, int flagDetectsBeginning = 1 );
		void findTailOfElementList( coordList *, coordList **& );
		void cycle( coordList * );
		void displayScreen( void );
		void displayElementList( coordList *src, int flagDetectsBeginning = 1 );
		
};

void displayClass::addElementToScreen( coordList *element, coordList *&prevFirst, coordList *&prevLast )
{
	if( elementList == NULL )
	{
		if( VERBOSE_MODE )
		{
			cout << "BRAND NEW---------------------" << endl;
		}

		copyElementListAndPrevPointers( element, elementList, prevFirst, prevLast );
		
		if( VERBOSE_MODE )
		{
			cout << "element redo" << endl;
			cycle( element );
			cout << "elementList After" << endl;
			cycle( elementList );
		}
	}
	else if( prevFirst != NULL )
	{
		// This element has been displayed before.
		//	Need to overwrite previous state.
		
		coordList **firstPointer;
		coordList *lastPointer;
		
		if( VERBOSE_MODE )
		{
			cout << "ADDING---------------------" << endl;
			cout << "First previous State:" << prevFirst->x << " " << prevFirst->y << " " << prevFirst->z << endl;
			cout << "Last previous State:" << prevLast->x << " " << prevLast->y << " " << prevLast->z << endl;

			cout << "incoming element:" << endl;
			cycle( element );
			cout << "Element List:" << endl;
			cycle( elementList );
		}

		findPrevElement( &elementList, prevFirst, prevLast, firstPointer, lastPointer ); 
 		deleteElementInList( *firstPointer, lastPointer );
		copyElementListAndPrevPointers( element, *firstPointer, prevFirst, prevLast, lastPointer );

		if( VERBOSE_MODE )
		{
			cout << "First previous State:" << prevFirst->x << " " << prevFirst->y << " " << prevFirst->z << endl;
			cout << "Last previous State:" << prevLast->x << " " << prevLast->y << " " << prevLast->z << endl;
			cout << "element redo" << endl;
			cycle( element );
			cout << "elementList After" << endl;
			cycle( elementList );
		}
	}
	else
	{
		// Not present in list.
		coordList **tail;

		if( VERBOSE_MODE )
		{
			cout << "TAIL---------------------" << endl;
			cout << "incoming element:" << endl;
			cycle( element );
			cout << "Element List:" << endl;
			cycle( elementList );
		}


		findTailOfElementList( elementList, tail );
		copyElementListAndPrevPointers( element, *tail, prevFirst, prevLast );
		
		if( VERBOSE_MODE )
		{
			cout << "element redo" << endl;
			cycle( element );
			cout << "elementList After" << endl;
			cycle( elementList );
		}
	}
}

void displayClass::copyElementList( coordList *source, coordList *&target )
{
	target = new coordList;
	target->x = source->x;
	target->y = source->y;
	target->z = source->z;


	if( source->nextPtr != NULL )
	{
		copyElementList( source->nextPtr, target->nextPtr );		
	}	
	else
	{
		target->nextPtr = NULL;
	}
}

void displayClass::findPrevElement( coordList **src, coordList *prevFirst, coordList *prevLast, coordList **&firstPointer, coordList *&lastPointer, int startingPointNotFound )
{
	// startingPointNotFound flag too confuzing?
		
	if( (*src)->x == prevFirst->x && (*src)->y == prevFirst->y && (*src)->z == prevFirst->z )
	{
		firstPointer = src;
		startingPointNotFound = 0;
	}

	if( (*src)->x == prevLast->x && (*src)->y == prevLast->y && (*src)->z == prevLast->z )
	{
		lastPointer = (*src)->nextPtr;
		return;
	}

	if( (*src)->nextPtr != NULL )
	{
		findPrevElement( &((*src)->nextPtr), prevFirst, prevLast, firstPointer, lastPointer, startingPointNotFound );		
	}
}

void displayClass::deleteElementInList( coordList *begin, coordList *end )
{	
	// Combine this method with findPrevElement.
	//	Inefficient cycles.  Need to optimize for uC

	if( begin->nextPtr != end )
	{
		deleteElementInList( begin->nextPtr, end );
	}
	
	delete begin;
}

void displayClass::copyElementListAndPrevPointers(	coordList *source, coordList *&target, coordList *&prevFirst, coordList *&prevLast, coordList *end, int atBeginning )
{
	if( atBeginning )
	{
		if( prevFirst == NULL )
		{
			prevFirst = new coordList;
		}

		prevFirst->x = source->x;
		prevFirst->y = source->y;
		prevFirst->z = source->z;

		atBeginning = 0;
	}

	target = new coordList;
	target->x = source->x;
	target->y = source->y;
	target->z = source->z;

	if( source->nextPtr != NULL )
	{
		copyElementListAndPrevPointers( source->nextPtr, target->nextPtr, prevFirst, prevLast, end, atBeginning );		
	}	
	else
	{
		if( prevLast == NULL )
		{
			prevLast = new coordList;
		}

		prevLast->x = source->x;
		prevLast->y = source->y;
		prevLast->z = source->z;
		
		if( end == NULL )
		{
			target->nextPtr = NULL;
		}
		else
		{
			target->nextPtr = end;
		}
	}
}

void displayClass::findTailOfElementList( coordList *source, coordList **&tail)
{
	if( source->nextPtr != NULL )
	{
		findTailOfElementList( source->nextPtr, tail );		
	}	
	else
	{
		tail = &source->nextPtr;
	}
}

void displayClass::displayScreen(  )
{
	glColor3f( 1.0, 1.0, 1.0 );
	
	displayElementList( elementList );
}

void displayClass::displayElementList( coordList *source, int atBeginning )
{
	if( atBeginning )
	{
		atBeginning = 0;
	}

	glVertex3f(	(float)source->x/10 - 0.75f, 
				(float)source->y/10 - 0.75f, 
				(float)source->z/10 - 0.75f );	

	if( source->nextPtr != NULL )
	{
		displayElementList( source->nextPtr, atBeginning );		
	}
}

void displayClass::cycle( coordList *source )
{
	cout << "Coords x:y:z = " << source->x << ":" << source->y << ":" << source->z << endl;

	if( source->nextPtr != NULL )
	{
		cycle( source->nextPtr );		
	}
}



